<?php

namespace App\Module\Sub;

use App\depository\ManageForbiddenDep;
use App\depository\ManagePlayerDep;
use App\depository\PermissionsDep;
use App\depository\RecordFlyDep;
use App\depository\RecordFriendKillDep;
use App\depository\RecordKillDep;
use App\depository\RecordPlayerDep;
use App\depository\RecordTalkDep;
use App\depository\RecordTeamDep;
use App\depository\MarkDep;
use App\depository\RoleHasPermissionsDep;
use App\depository\RolesDep;
use App\depository\SteamIDEosidDep;
use App\depository\SubPermissionsDep;
use App\depository\SubUserHasRolesDep;
use App\depository\TeamDictDep;
use App\depository\TeamsDep;
use App\depository\UserHasTeamsDep;
use App\Enum\CommonEnum;
use App\Enum\PermissionsEnum;
use App\Enum\RolesEnum;
use App\Module\BaseModule;
use App\Service\DictService;
use App\depository\SubRolesDep;
use App\depository\SubRoleHasPermissionsDep;
use App\depository\ManageMapDep;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Auth;

class SubGamerModule extends BaseModule
{

    public function init($request)
    {

        $param = $request->input();
        $dictService = new DictService();

        $dictService->setPermissions('/play/gamer');

        $data = [
            'dict' => $dictService->getDict(),
        ];

        return self::response($data);
    }


    public function add($request)
    {
        $param = $request->input();

        $teamId = $request->headers->get('TeamId');

        if (empty($param['name'])) {
            return self::response([], '请填写标题', 100);
        }

        if (empty($param['guard_name'])) {
            return self::response([], '请填写标识', 100);
        }

        $dep = new SubRolesDep($teamId);
        $roleHasPermissionsDep = new SubRoleHasPermissionsDep();

        $res = $dep->firstByGuardName($param['guard_name']);
        if ($res) {
            return self::response([], '角色标识已存在，请重新输入', 200);
        }

        $data = [
            'team_id' => $teamId,
            'name' => $param['name'],
            'guard_name' => $param['guard_name'],
            'remark' => $param['remark'] ?? "",
            'status' => $param['status']
        ];

        $roleId = $dep->addGetId($data);
        if (!empty($param['permission_id'])) {
            foreach ($param['permission_id'] as $permissionId) {
                $data = [
                    'team_id' => $teamId,
                    'role_id' => $roleId,
                    'permission_id' => $permissionId
                ];
                $roleHasPermissionsDep->add($data);
            }
        }
        return self::response();
    }

    public function del($request)
    {
        $param = $request->input();

        $dep = new ManageMapDep();

        $dep->del($param['id']);
        return self::response();
    }

    public function edit($request)
    {
        $param = $request->input();
        $teamId = $request->headers->get('TeamId');

        if (empty($param['name'])) {
            return self::response([], '请填写标题', 100);
        }

        if (empty($param['guard_name'])) {
            return self::response([], '请填写标识', 100);
        }

        $data = [
            'name' => $param['name'],
            'guard_name' => $param['guard_name'],
            'remark' => $param['remark'] ?? "",
            'status' => $param['status']
        ];

        $dep = new SubRolesDep();
        $dep->upd($param['id'], $data);

        $roleHasPermissionsDep = new SubRoleHasPermissionsDep();
        $roleHasPermissionsDep->delByRoleId($param['id']);

        if (!empty($param['permission_id'])) {
            foreach ($param['permission_id'] as $permissionId) {
                $data = [
                    'team_id' => $teamId,
                    'role_id' => $param['id'],
                    'permission_id' => $permissionId
                ];
                $roleHasPermissionsDep->add($data);
            }
        }

        return self::response();
    }

    public function list($request)
    {
        $param = $request->input();

        $teamId = $request->headers->get('TeamId');

        $mapDep = new ManagePlayerDep();
        $resList = $mapDep->list($teamId);

        $data['total'] = $resList->count();

        $squadArr = [];
        $teamArr = [];
        
    
        $list = $resList->map(function ($item) use (&$squadArr, &$teamArr) {
            if (!array_key_exists("{$item->team_id}_{$item->squad_id}", $squadArr)) {
                $squadArr["{$item->team_id}_{$item->squad_id}"] = $item->squad_name;
            }
            if (!array_key_exists($item->team_id, $teamArr)) {
                $teamArr[$item->team_id] = $item->team_name;
            }
            return [
                'id' => $item->id,
                'player_id' => $item->playerid,
                'steamid' => $item->steamid,
                'name' => $item->name,
                'is_leader' => $item->is_leader,
                'role' => $item->role,
                'squad_id' => $item->squad_id,
                'squad_name' => $item->squad_name,
                'team_id' => $item->team_id,
                'team_name' => $item->team_name,
                'sum' => $item->sum,
            ];
        })->groupBy('team_id');

        $list->each(function ($item, $index) use (&$list) {
            $list[$index] = $item->groupBy('squad_id');
        });

        $data['list'] = $list;
        $data['squad'] = $squadArr;
        $data['team'] = $teamArr;

        return self::response($data);
    }

    public function permissionsTree()
    {

        $permissionsDep = new SubPermissionsDep();
        $resAllPermissions = $permissionsDep->normal();

        $allPermissions = $resAllPermissions->map(function ($item) {
            return [
                'id' => $item->id,
                'label' => $item->name,
                'remark' => $item->remark,
                'parent_id' => $item->parent_id,
                'type' => $item->type,
                'type_show' => PermissionsEnum::$typeArr[$item->type] ?? CommonEnum::DEFAULT_NULL,
                'icon' => $item->icon,
                'guard_name' => $item->guard_name,
                'status' => $item->status,
                'status_show' => PermissionsEnum::$statusArr[$item->status] ?? CommonEnum::DEFAULT_NULL
            ];
        });

        $tree = $this->listToTree($allPermissions->toArray());
        return $tree;
    }


    public function listToTree($list, $rootId = 0)
    {
        $arr = [];
        foreach ($list as $item) {
            if ($item['parent_id'] == $rootId) {
                $children = $this->listToTree($list, $item['id']);
                if ($children) {
                    $item['children'] = $children;
                }
                $arr[] = $item;
            }
        }
        return $arr;
    }

    public function detail($request)
    {

        $param = $request->input();
        $teamId = $request->headers->get('TeamId');
        $user = $request->user();

        $eosDep = new SteamIDEosidDep();
        $gamerDep = new ManagePlayerDep();

        $resEos = $eosDep->firstBySteamid($param['steamid']);
        $data['detail'] = [
            'steamid' => $param['steamid'],
            'eosid' => $resEos ? $resEos->eosid : CommonEnum::DEFAULT_NULL,
        ];


        //        $resGamer = $gamerDep->firstBySteamid($param['steamid']);
        //        if (!$resGamer) {
        //            return self::response([], '未查询到玩家信息', 200);
        //        }
        $userHasTeamsDep = new UserHasTeamsDep();
        $resUserHasTeam = $userHasTeamsDep->firstByTeamIdUserId($teamId, $user->id);
        if (!$resUserHasTeam) {
            $subUserHasRolesDep = new SubUserHasRolesDep();
            $resRole = $subUserHasRolesDep->firstByUserId($teamId, $user->id);
            if (!$resRole) {
                $data['list'] = [];
                return self::response($data);
            }

            $subRoleHasPermissionDep = new SubRoleHasPermissionsDep();
            $resPermissions = $subRoleHasPermissionDep->getByRoleId($resRole->role_id);;
            if ($resPermissions->isEmpty()) {
                $data['list'] = [];
                return self::response($data);
            }

            $permissionDep = new SubPermissionsDep();
            $guardArr = $resPermissions->map(function ($item) use ($permissionDep) {
                $resPermission = $permissionDep->first($item->permission_id);
                return $resPermission->guard_name;
            })->toArray();

            $resList = [];
            if (in_array('/game/fly', $guardArr)) {
                $recordFlyDep = new RecordFlyDep();
                $resFly = $recordFlyDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '飞天记录',
                        'type' => 'fly',
                        'content' => "{$item->player_name} - {$item->player_handle}",
                        'content_arr' => [
                            [
                                "content" => $item->player_name . " - ",
                                'type' => 'text'
                            ],
                            [
                                "content" => $item->player_handle,
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resFly = collect([]);
            }

            if (in_array('/game/kill', $guardArr)) {
                $recordKillDep = new RecordKillDep();
                $resKill = $recordKillDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '击杀记录',
                        'type' => 'kill',
                        'content' => "{$item->murderer}({$item->murderer_steamid}) {$item->hurt_type} {$item->hurt_num} {$item->victim}($item->victim_steamid) - {$item->weapon}",
                        'content_arr' => [
                            [
                                "content" => "{$item->murderer}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->murderer_steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ") {$item->hurt_type} {$item->hurt_num} {$item->victim}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->victim_steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ") - {$item->weapon}",
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resKill = collect([]);
            }

            if (in_array('/game/team', $guardArr)) {

                $recordTeam = new RecordTeamDep();
                $resTeam = $recordTeam->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '建队记录',
                        'type' => 'team',
                        'content' => "{$item->player_name}({$item->steamid}) 在 {$item->camp} 建立了队伍 {$item->team_id} - {$item->team_name}",
                        'content_arr' => [
                            [
                                "content" => "{$item->player_name}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ") 在 {$item->camp} 建立了队伍 {$item->team_id} - {$item->team_name}",
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resTeam = collect([]);
            }

            if (in_array('/game/talk', $guardArr)) {
                $recordTalk = new RecordTalkDep();
                $resTalk = $recordTalk->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '聊天记录',
                        'type' => 'talk',
                        'content' => "{$item->channel} - {$item->player_name}({$item->steamid}): {$item->content}",
                        'content_arr' => [
                            [
                                "content" => "{$item->channel} - {$item->player_name}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => "): {$item->content}",
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resTalk = collect([]);
            }


            if (in_array('/game/friendkill', $guardArr)) {
                $recordFriendKillDep = new RecordFriendKillDep();
                $resFriendKill = $recordFriendKillDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '友伤记录',
                        'type' => 'friendKill',
                        'content' => "{$item->murderer_name}({$item->murderer_steamid}) 击杀了友军 {$item->victim_name}($item->victim_steamid)",
                        'content_arr' => [
                            [
                                "content" => "{$item->murderer_name}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->murderer_steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ") 击杀了友军 {$item->victim_name}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->victim_steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ")",
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resFriendKill = collect([]);
            }

            if (in_array('/game/player', $guardArr)) {
                $recordPlayerDep = new RecordPlayerDep();
                $resPlayer = $recordPlayerDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                    return [
                        'date' => $item->date,
                        'type_show' => '玩家记录',
                        'type' => 'player',
                        'content' => "{$item->player_name}($item->steamid) - {$item->content}",
                        'content_arr' => [
                            [
                                "content" => "{$item->player_name}(",
                                'type' => 'text'
                            ],
                            [
                                "content" => "{$item->steamid}",
                                'type' => 'id'
                            ],
                            [
                                "content" => ") - {$item->content}",
                                'type' => 'text'
                            ],
                        ]
                    ];
                });
            } else {
                $resPlayer = collect([]);
            }

            $mergeList = array_merge($resFly->toArray(), $resKill->toArray(), $resTeam->toArray(), $resTalk->toArray(), $resFriendKill->toArray(), $resPlayer->toArray());

            array_multisort(array_column($mergeList, 'date'), SORT_DESC, $mergeList);

            $resList = array_splice($mergeList, 0, 50);

            $data['list'] = $resList;

            return self::response($data);
        } else {

            $recordFlyDep = new RecordFlyDep();
            $resFly = $recordFlyDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '飞天记录',
                    'type' => 'fly',
                    'content' => "{$item->player_name} - {$item->player_handle}",
                    'content_arr' => [
                        [
                            "content" => $item->player_name . " - ",
                            'type' => 'text'
                        ],
                        [
                            "content" => $item->player_handle,
                            'type' => 'text'
                        ],
                    ]
                ];
            });


            $recordKillDep = new RecordKillDep();
            $resKill = $recordKillDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '击杀记录',
                    'type' => 'kill',
                    'content' => "{$item->murderer}({$item->murderer_steamid}) {$item->hurt_type} {$item->hurt_num} {$item->victim}($item->victim_steamid) - {$item->weapon}",
                    'content_arr' => [
                        [
                            "content" => "{$item->murderer}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->murderer_steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ") {$item->hurt_type} {$item->hurt_num} {$item->victim}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->victim_steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ") - {$item->weapon}",
                            'type' => 'text'
                        ],
                    ]
                ];
            });


            $recordTeam = new RecordTeamDep();
            $resTeam = $recordTeam->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '建队记录',
                    'type' => 'team',
                    'content' => "{$item->player_name}({$item->steamid}) 在 {$item->camp} 建立了队伍 {$item->team_id} - {$item->team_name}",
                    'content_arr' => [
                        [
                            "content" => "{$item->player_name}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ") 在 {$item->camp} 建立了队伍 {$item->team_id} - {$item->team_name}",
                            'type' => 'text'
                        ],
                    ]
                ];
            });

            $recordTalk = new RecordTalkDep();
            $resTalk = $recordTalk->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '聊天记录',
                    'type' => 'talk',
                    'content' => "{$item->channel} - {$item->player_name}({$item->steamid}): {$item->content}",
                    'content_arr' => [
                        [
                            "content" => "{$item->channel} - {$item->player_name}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => "): {$item->content}",
                            'type' => 'text'
                        ],
                    ]
                ];
            });


            $recordFriendKillDep = new RecordFriendKillDep();
            $resFriendKill = $recordFriendKillDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '友伤记录',
                    'type' => 'friendKill',
                    'content' => "{$item->murderer_name}({$item->murderer_steamid}) 击杀了友军 {$item->victim_name}($item->victim_steamid)",
                    'content_arr' => [
                        [
                            "content" => "{$item->murderer_name}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->murderer_steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ") 击杀了友军 {$item->victim_name}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->victim_steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ")",
                            'type' => 'text'
                        ],
                    ]
                ];
            });


            $recordPlayerDep = new RecordPlayerDep();
            $resPlayer = $recordPlayerDep->getRecent($teamId, $param['steamid'])->map(function ($item) {
                return [
                    'date' => $item->date,
                    'type_show' => '玩家记录',
                    'type' => 'player',
                    'content' => "{$item->player_name}($item->steamid) - {$item->content}",
                    'content_arr' => [
                        [
                            "content" => "{$item->player_name}(",
                            'type' => 'text'
                        ],
                        [
                            "content" => "{$item->steamid}",
                            'type' => 'id'
                        ],
                        [
                            "content" => ") - {$item->content}",
                            'type' => 'text'
                        ],
                    ]
                ];
            });


            $mergeList = array_merge($resFly->toArray(), $resKill->toArray(), $resTeam->toArray(), $resTalk->toArray(), $resFriendKill->toArray(), $resPlayer->toArray());

            array_multisort(array_column($mergeList, 'date'), SORT_DESC, $mergeList);

            $resList = array_splice($mergeList, 0, 50);

            $data['list'] = $resList;

            return self::response($data);
        }
    }

    public function option($request)
    {
        $param = $request->input();
        $teamId = $request->headers->get('TeamId');

        if (in_array($param['type'], ['out', 'warning', 'black']) && empty($param['reason'])) {
            return self::response([], '请输入操作理由', 100);
        }

        $user = $request->user();

        $teamDep = new TeamsDep();
        $resTeam = $teamDep->first($teamId);

        $text = $resTeam->reason ?: '{理由}';

        $dictDep = new TeamDictDep();
        $resDict = $dictDep->getByTeamId($teamId);

        $rcon = $resDict->first(function ($item) {
            return $item->label == 'RCON地址';
        });
        if (!$rcon) {
            return self::response([], '请联系管理员添加RCON地址', 200);
        }

        $str = str_replace('{理由}', $param['reason'], $text);
        $str = str_replace('{名称}', $user->nickname, $str);
        $client = new Client();

        if ($param['type'] === 'out') {
            $url = $rcon->value . "AdminKick {$param['steamid']} " . $str;
            $response = $client->get($url);
        }

        if ($param['type'] === 'warning') {
            $url = $rcon->value . "AdminWarn {$param['steamid']} " . $str;
            $response = $client->get($url);
        }

        if ($param['type'] === 'remove') {
            $url = $rcon->value . "AdminForceTeamChange {$param['steamid']}";
            $response = $client->get($url);
        }

        if ($param['type'] === 'removeTeam') {
            $url = $rcon->value . "AdminRemovePlayerFromSquad {$param['steamid']}";
            $response = $client->get($url);
        }

        $body = $response->getBody();
        $bodyStr = (string)$body;
        if (!$bodyStr) {
            return self::response([], '连接失败', 200);
        }

        return self::response([], $bodyStr);
    }

    public function teamOption($request)
    {

        $param = $request->input();
        $teamId = $request->headers->get('TeamId');

        $dictDep = new TeamDictDep();
        $resDict = $dictDep->getByTeamId($teamId);

        $rcon = $resDict->first(function ($item) {
            return $item->label == 'RCON地址';
        });
        if (!$rcon) {
            return self::response([], '请联系管理员添加RCON地址', 200);
        }

        $client = new Client();
        if ($param['type'] === 'cancel') {
            $url = $rcon->value . "AdminDisbandSquad {$param['teamId']} {$param['squadId']}";
            $response = $client->get($url);
        }

        if ($param['type'] === 'reset') {
            $url = $rcon->value . "AdminRenameSquad {$param['teamId']} {$param['squadId']}";
            $response = $client->get($url);
        }

        $body = $response->getBody();
        $bodyStr = (string)$body;
        if (!$bodyStr) {
            return self::response([], '连接失败', 200);
        }

        return self::response([], $bodyStr);
    }


    public function globalOption($request)
    {
        $param = $request->input();

        $teamId = $request->headers->get('TeamId');

        $dictDep = new TeamDictDep();
        $resDict = $dictDep->getByTeamId($teamId);

        $rcon = $resDict->first(function ($item) {
            return $item->label == 'RCON地址';
        });
        if (!$rcon) {
            return self::response([], '请联系管理员添加RCON地址', 200);
        }

        $client = new Client();
        if ($param['type'] === 'cancelGamer') {
            $url = $rcon->value . "AdminForceAllRoleAvailability 1";
            $response = $client->get($url);
        }

        if ($param['type'] === 'lockGamer') {
            $url = $rcon->value . "AdminForceAllRoleAvailability 0";
            $response = $client->get($url);
        }

        if ($param['type'] === 'cancelCar') {
            $url = $rcon->value . "AdminDisableVehicleClaiming 1";
            $response = $client->get($url);
        }

        if ($param['type'] === 'lockCar') {
            $url = $rcon->value . "AdminDisableVehicleClaiming 0";
            $response = $client->get($url);
        }

        if ($param['type'] === 'cancelHand') {
            $url = $rcon->value . "AdminForceAllDeployableAvailability 1";
            $response = $client->get($url);
        }

        if ($param['type'] === 'lockHand') {
            $url = $rcon->value . "AdminForceAllDeployableAvailability 0";
            $response = $client->get($url);
        }

        $body = $response->getBody();
        $bodyStr = (string)$body;
        if (!$bodyStr) {
            return self::response([], '连接失败', 200);
        }

        return self::response([], $bodyStr);
    }

    public function black($request)
    {

        $param = $request->input();
        $teamId = $request->headers->get('TeamId');
        $user = $request->user();

        if (empty($param['reason'])) {
            return self::response([], '请输入操作理由', 100);
        }

        $dictDep = new TeamDictDep();
        $resDict = $dictDep->getByTeamId($teamId);

        $teamDep = new TeamsDep();
        $resTeam = $teamDep->first($teamId);

        $text = $resTeam->reason ?: '{理由}';
        $rcon = $resDict->first(function ($item) {
            return $item->label == 'RCON地址';
        });
        if (!$rcon) {
            return self::response([], '请联系管理员添加RCON地址', 200);
        }

        $days = $param['days'] > 0 ? "{$param['days']}d" : 0;
        $str = str_replace('{理由}', $param['reason'], $text);
        $str = str_replace('{名称}', $user->nickname, $str);

        $client = new Client();
        $url = $rcon->value . "AdminBan {$param['steamid']} {$days} {$str}";
        $response = $client->get($url);

        $body = $response->getBody();
        $bodyStr = (string)$body;
        if (!$bodyStr) {
            return self::response([], '连接失败', 200);
        }

        return self::response([], $bodyStr);
    }
}
